home *** CD-ROM | disk | FTP | other *** search
- /* xlmath - xlisp builtin arithmetic functions */
-
- #include "xlisp.h"
-
- /* external variables */
- extern NODE *xlstack;
- extern NODE *true;
-
- /* forward declarations */
- FORWARD NODE *unary();
- FORWARD NODE *binary();
- FORWARD NODE *predicate();
- FORWARD NODE *compare();
-
- /* xadd - builtin function for addition */
- NODE *xadd(args)
- NODE *args;
- {
- return (binary(args,'+'));
- }
-
- /* xsub - builtin function for subtraction */
- NODE *xsub(args)
- NODE *args;
- {
- return (binary(args,'-'));
- }
-
- /* xmul - builtin function for multiplication */
- NODE *xmul(args)
- NODE *args;
- {
- return (binary(args,'*'));
- }
-
- /* xdiv - builtin function for division */
- NODE *xdiv(args)
- NODE *args;
- {
- return (binary(args,'/'));
- }
-
- /* xrem - builtin function for remainder */
- NODE *xrem(args)
- NODE *args;
- {
- return (binary(args,'%'));
- }
-
- /* xmin - builtin function for minimum */
- NODE *xmin(args)
- NODE *args;
- {
- return (binary(args,'m'));
- }
-
- /* xmax - builtin function for maximum */
- NODE *xmax(args)
- NODE *args;
- {
- return (binary(args,'M'));
- }
-
- /* xbitand - builtin function for bitwise and */
- NODE *xbitand(args)
- NODE *args;
- {
- return (binary(args,'&'));
- }
-
- /* xbitior - builtin function for bitwise inclusive or */
- NODE *xbitior(args)
- NODE *args;
- {
- return (binary(args,'|'));
- }
-
- /* xbitxor - builtin function for bitwise exclusive or */
- NODE *xbitxor(args)
- NODE *args;
- {
- return (binary(args,'^'));
- }
-
- /* binary - handle binary operations */
- LOCAL NODE *binary(args,fcn)
- NODE *args; int fcn;
- {
- int ival,iarg;
- NODE *val;
-
- /* get the first argument */
- ival = xlmatch(INT,&args)->n_int;
-
- /* treat '-' with a single argument as a special case */
- if (fcn == '-' && args == NULL)
- ival = -ival;
-
- /* handle each remaining argument */
- while (args) {
-
- /* get the next argument */
- iarg = xlmatch(INT,&args)->n_int;
-
- /* accumulate the result value */
- switch (fcn) {
- case '+': ival += iarg; break;
- case '-': ival -= iarg; break;
- case '*': ival *= iarg; break;
- case '/': ival /= iarg; break;
- case '%': ival %= iarg; break;
- case 'M': if (iarg > ival) ival = iarg; break;
- case 'm': if (iarg < ival) ival = iarg; break;
- case '&': ival &= iarg; break;
- case '|': ival |= iarg; break;
- case '^': ival ^= iarg; break;
- }
- }
-
- /* initialize value */
- val = newnode(INT);
- val->n_int = ival;
-
- /* return the result value */
- return (val);
- }
-
- /* xbitnot - bitwise not */
- NODE *xbitnot(args)
- NODE *args;
- {
- return (unary(args,'~'));
- }
-
- /* xabs - builtin function for absolute value */
- NODE *xabs(args)
- NODE *args;
- {
- return (unary(args,'A'));
- }
-
- /* xadd1 - builtin function for adding one */
- NODE *xadd1(args)
- NODE *args;
- {
- return (unary(args,'+'));
- }
-
- /* xsub1 - builtin function for subtracting one */
- NODE *xsub1(args)
- NODE *args;
- {
- return (unary(args,'-'));
- }
-
- /* unary - handle unary operations */
- LOCAL NODE *unary(args,fcn)
- NODE *args; int fcn;
- {
- NODE *val;
- int ival;
-
- /* get the argument */
- ival = xlmatch(INT,&args)->n_int;
- xllastarg(args);
-
- /* compute the result */
- switch (fcn) {
- case '~': ival = ~ival; break;
- case 'A': if (ival < 0) ival = -ival; break;
- case '+': ival++; break;
- case '-': ival--; break;
- }
-
- /* convert the value */
- val = newnode(INT);
- val->n_int = ival;
-
- /* return the result value */
- return (val);
- }
-
- /* xminusp - is this number negative? */
- NODE *xminusp(args)
- NODE *args;
- {
- return (predicate(args,'-'));
- }
-
- /* xzerop - is this number zero? */
- NODE *xzerop(args)
- NODE *args;
- {
- return (predicate(args,'Z'));
- }
-
- /* xplusp - is this number positive? */
- NODE *xplusp(args)
- NODE *args;
- {
- return (predicate(args,'+'));
- }
-
- /* xevenp - is this number even? */
- NODE *xevenp(args)
- NODE *args;
- {
- return (predicate(args,'E'));
- }
-
- /* xoddp - is this number odd? */
- NODE *xoddp(args)
- NODE *args;
- {
- return (predicate(args,'O'));
- }
-
- /* predicate - handle a predicate function */
- LOCAL NODE *predicate(args,fcn)
- NODE *args; int fcn;
- {
- NODE *val;
- int ival;
-
- /* get the argument */
- ival = xlmatch(INT,&args)->n_int;
- xllastarg(args);
-
- /* compute the result */
- switch (fcn) {
- case '-': ival = (ival < 0); break;
- case 'Z': ival = (ival == 0); break;
- case '+': ival = (ival > 0); break;
- case 'E': ival = ((ival & 1) == 0); break;
- case 'O': ival = ((ival & 1) != 0); break;
- }
-
- /* return the result value */
- return (ival ? true : NULL);
- }
-
- /* xlss - builtin function for < */
- NODE *xlss(args)
- NODE *args;
- {
- return (compare(args,'<'));
- }
-
- /* xleq - builtin function for <= */
- NODE *xleq(args)
- NODE *args;
- {
- return (compare(args,'L'));
- }
-
- /* equ - builtin function for = */
- NODE *xequ(args)
- NODE *args;
- {
- return (compare(args,'='));
- }
-
- /* xneq - builtin function for /= */
- NODE *xneq(args)
- NODE *args;
- {
- return (compare(args,'#'));
- }
-
- /* xgeq - builtin function for >= */
- NODE *xgeq(args)
- NODE *args;
- {
- return (compare(args,'G'));
- }
-
- /* xgtr - builtin function for > */
- NODE *xgtr(args)
- NODE *args;
- {
- return (compare(args,'>'));
- }
-
- /* compare - common compare function */
- LOCAL NODE *compare(args,fcn)
- NODE *args; int fcn;
- {
- NODE *arg1,*arg2;
- int cmp;
-
- /* get the two arguments */
- arg1 = xlarg(&args);
- arg2 = xlarg(&args);
- xllastarg(args);
-
- /* do the compare */
- if (stringp(arg1) && stringp(arg2))
- cmp = strcmp(arg1->n_str,arg2->n_str);
- else if (fixp(arg1) && fixp(arg2))
- cmp = arg1->n_int - arg2->n_int;
- else
- cmp = arg1 - arg2;
-
- /* compute result of the compare */
- switch (fcn) {
- case '<': cmp = (cmp < 0); break;
- case 'L': cmp = (cmp <= 0); break;
- case '=': cmp = (cmp == 0); break;
- case '#': cmp = (cmp != 0); break;
- case 'G': cmp = (cmp >= 0); break;
- case '>': cmp = (cmp > 0); break;
- }
-
- /* return the result */
- return (cmp ? true : NULL);
- }